﻿using System;
using System.Text;

public class Usuario : Entidad
{
    #region Atributos de la clase

    protected DatosDeUsuario misDatos;

    #endregion

    #region Métodos de acceso

    protected DatosDeUsuario getMisDatos()
    {
        return this.misDatos;
    }
    protected void setMisDatos(DatosDeUsuario pMisDatos)
    {
        this.misDatos = pMisDatos;
    }

    #endregion

    #region Propiedades públicas

    public DatosDeUsuario MisDatos
    { 
        get { return this.getMisDatos(); }
        set { this.setMisDatos(value); }
    }

    #endregion

    #region Contructores

    public Usuario(DatosDeUsuario pDatosDeUsuario)
    {
        this.setMisDatos(pDatosDeUsuario);
    }        
    internal Usuario()
    {
        this.setMisDatos(null);
    }
        
    /**
        * \brief Constructor de copia para la clase Usuario.
        * \param pUsuario - Usuario sobre el que se realiza la copia.
        * \return Usuario inicializado y listo para usarse.
        */
    protected Usuario(Usuario pUsuario)
    {
        this.setMisDatos((DatosDeUsuario)pUsuario.MisDatos.dameCopiaEncapsulado());
    }

    #endregion

    #region Métodos Adicionales
    /**
        * \brief Sobrecarga del operador de conversión a string de una Usuario.
        * \return Un string con la información de la clase Usuario del objeto.
        */
    public override string ToString()
    {
        StringBuilder cadena = new StringBuilder(this.misDatos.ToString());

        return cadena.ToString();
    }
    /**
        * \brief Sobrecarga del operador lógico de igualdad entre dos objetos Usuario.
        * \pre Los objetos comparados deben pertenecer a la clase Usuario.
        * \pre La entidad Usuario debe de ser válida.
        * \param obj - Objeto Usuario a comparar.
        * \return True si los objetos comparados referencian al mismo encapsulado DatosDeUsuario, False en otro caso.
        */
    public override bool Equals(object obj)
    {
        try
        {
            Usuario usuario = (Usuario)obj;

            if (this.MisDatos.Equals(usuario.getMisDatos()))
                if (this.MisDatos.Id.Equals(0))
                    return this.GetHashCode().Equals(obj.GetHashCode());
                else
                    return true;
            else
                return false;
        }
        catch (Exception)
        {
            throw new Exception("Error: Método Equals; Clase Usuario; No se pueden comparar dos objetos distintos");
        }
    }
    /**
        * \brief Sobrecarga del operador del codigo hash de una Usuario.
        * \return Un entero con el codigo Hash de la clase Perfil del objeto.
        */
    public override int GetHashCode()
    {
        //Definimos un numero entero primo
        int primo = 31;
        int resultado = 1;

        resultado = primo * resultado + ((this.MisDatos == null) ? 0 : this.MisDatos.GetHashCode());

        return resultado;
    }

    internal override Entidad dameCopiaEntidad()
    {
        return new Usuario(this);
    }

    internal override void restaurarEntidad(Entidad pEntidad)
    {
        Usuario pUsuario = (Usuario)pEntidad;

        this.MisDatos.restaurarEncapsulado(pUsuario.MisDatos);
    }

    #endregion
}